package com.teaphy.teacompiler.module;

import com.teaphy.teaannotation.annotation.Factory;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;

public class FactoryAnnotatedClass {
	
	// 被注解的元素
	private TypeElement annotatedElement;
	private String qualifiedSuperClassName;
	private String simpleTypeName;
	private String id;
	
	public FactoryAnnotatedClass(TypeElement typeElement) throws IllegalAccessException {
		this.annotatedElement = typeElement;
		
		Factory factory = typeElement.getAnnotation(Factory.class);
		
		if (null == factory) {
			throw new IllegalAccessException(String
				.format("%s is't annotated by %s", typeElement.getSimpleName(),
					Factory.class.getSimpleName()));
			
		}
		
		id = factory.id();
		
		if (id.length() == 0) {
			throw new IllegalAccessException(
				String.format("id() in @%s for class %s is null or empty! that's not allowed",
					Factory.class.getSimpleName(), typeElement.getQualifiedName().toString()));
		}
		
		try {
			// 1. 这个还没有被编译：这种情况是我们尝试编译被@Fractory注解的源代码
			Class clz = factory.type();
			qualifiedSuperClassName = clz.getCanonicalName();
			simpleTypeName = clz.getSimpleName();
		} catch (MirroredTypeException mte) {
			// 2. 这个类已经被编译.如果第三方.jar包含已编译的被@Factory注解.class文件。在这种情况下，我们可以想try中那块代码中所示直接获取Class
			// MirroredTypeException包含一个TypeMirror，它表示我们未编译类。
			// 1. 直接强制转换为DeclaredType
			DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror();
			// 2. 读取TypeElement来获取合法的名字
			TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
			qualifiedSuperClassName = classTypeElement.getQualifiedName().toString();
			simpleTypeName = classTypeElement.getSimpleName().toString();
		}
	}
	
	public TypeElement getAnnotatedElement() {
		return annotatedElement;
	}
	
	public String getQualifiedSuperClassName() {
		return qualifiedSuperClassName;
	}
	
	public String getSimpleTypeName() {
		return simpleTypeName;
	}
	
	public String getId() {
		return id;
	}
	
	@Override
	public String toString() {
		return "FactoryAnnotatedClass{" +
			"annotatedElement=" + annotatedElement +
			", qualifiedSuperClassName='" + qualifiedSuperClassName + '\'' +
			", simpleTypeName='" + simpleTypeName + '\'' +
			", id='" + id + '\'' +
			'}';
	}
}
